from enum import Enum


class Player(Enum):
    DEFAULT = 0,
    PLAYER_A = 1,
    PLAYER_B = 2,


class GameLocal:
    def __init__(self):
        self.g_size = 3 * 3
        self.index_ = 0
        self.checkerboard = [0] * 9

    def init_game(self):
        print("Game start!")
        self.index_ = 0
        self.checkerboard = [0] * 9
        self.print_checkerboard()

    def start_game(self):
        self.init_game()
        winner = Player.DEFAULT
        while self.index_ < self.g_size:
            while True:
                input_number = int(input("Please input number of location you want to put: "))
                if input_number < 1 or input_number > 9:
                    print("Current location if already been typed in!")
                elif self.checkerboard[input_number - 1] != 0:
                    print("Input number should in the range of 1~9, please retype!")
                else:
                    break
            self.refresh_checkerboard(input_number)
            if self.index_ >= 4:
                is_game_over, winner = self.get_result()
                if is_game_over:
                    break
            self.index_ += 1
        if winner != Player.DEFAULT:
            print("Game over, the winner is {}!".format(winner.name))
        else:
            print("Game over, there's no winner.")

    def print_checkerboard(self):
        char_dict = {
            0: "[1]",
            1: "[2]",
            2: "[3]",
            3: "[4]",
            4: "[5]",
            5: "[6]",
            6: "[7]",
            7: "[8]",
            8: "[9]",
        }
        for i in range(9):
            if self.checkerboard[i] == 0:
                target_char = char_dict[i]
            elif self.checkerboard[i] == 1:
                target_char = "[X]"
            elif self.checkerboard[i] == 2:
                target_char = "[O]"
            else:
                target_char = ""
                print("Server error!")
            print(target_char, end="")
            if (i + 1) % 3 == 0:
                print("")
            else:
                print(",", end="")

    def refresh_checkerboard(self, index):
        value = 1 if (self.index_ & 1) == 0 else 2
        self.checkerboard[index - 1] = value
        self.print_checkerboard()

    def get_result(self):
        winner = Player.DEFAULT
        if self._is_slant_same_line() or self._is_vertical_same_line() or self._is_horizontal_same_line():
            winner = Player.PLAYER_A if (self.index_ & 1) == 0 else Player.PLAYER_B
            return True, winner
        return False, winner

    def _is_horizontal_same_line(self):
        find_vec = [0, 3, 6]
        for num in find_vec:
            if self.checkerboard[num] != 0 and (self.checkerboard[num] == self.checkerboard[num + 1] == self.checkerboard[num + 2]):
                return True
        return False

    def _is_vertical_same_line(self):
        find_vec = [0, 1, 2]
        for num in find_vec:
            if self.checkerboard[num] != 0 and (self.checkerboard[num] == self.checkerboard[num + 3] == self.checkerboard[num + 6]):
                return True
        return False

    def _is_slant_same_line(self):
        return self.checkerboard[0] == self.checkerboard[4] == self.checkerboard[8] or \
               self.checkerboard[2] == self.checkerboard[4] == self.checkerboard[6]


def main():
    game = GameLocal()
    game.start_game()


if __name__ == "__main__":
    main()
